--Event Engine
local EventEngine						=	class('EventEngine')

local ANONYMOUS = {}
local hashlist = {}

function EventEngine:ctor( ... )
	self._listeners = {}
end

--listener:The callback function
--owner:The object of the callback function
function EventEngine:AddEventListener( eventId,listener,owner,priority )
	local list = self._listeners[eventId]
	if not list then
		list = hashlist.new()
		self._listeners[eventId] = list
	end
	list:insert(owner or ANONYMOUS,listener,priority)
end

function EventEngine:RemoveEventListener(eventId,listener,owner)
	local list = self._listeners[eventId]
	if list then
		list:remove(owner or ANONYMOUS ,listener)
		if list:empty() then
			self._listeners[eventId] = nil
		end
	end
end

function EventEngine:DispatchEvent( eventId, ... )
	if self._listeners[eventId] then
        for _, owner, listener in pairs(self._listeners[event]) do
            if owner == ANONYMOUS then
                listener(event,...)
            else
                listener(owner, event, ...)
            end
        end
        return true
	end
	return false
end


----------------hashlist----------------------


hashlist._index = hashlist

function hashlist.new( ... )
	local self = setmetatable({},hashlist)
	self.header = {}
	self.header.next = self.header
	self.header.prev = self.header
	self.entries = {}  --The same eventID can have different callback function 
	return self
end

local function hashlist:makeIndex( owner,listener )
	return tostring(owner)..'|'..tostring(listener)
end

function hashlist:insert( key,value,priority )
	local idx = makeIndex(key,value)

	if self.entries[idx] then return end

	local entry = {key = key,value = value,priority = priority}

	local header,current = self.header
	if not priority then
		current = header.prev
	else
		current = header
		local nextList = current.next
		while nextList ~= header do
			if not nextList.priority or priority <= nextList.priority then
				break
			else
				current = nextList
				nextList = current.next
			end
		end
	end

	entry.next = current.next
	entry.prev = current
	current.next.prev = entry
	current.next = entry

	self.entries[idx] = entry
end

function hashlist:remove( key,value )
	local idx = makeIndex(key,value)
	local entry = self.entries[idx]
	if entry then
		entry.prev.next = entry.next
		entry.next.prev = entry.prev
		self.entries[idx] = nil
	end
end

function hashlist:empty( ... )
	return next(self.entries) == nil
end

-------参数获取？？？？--------------
local function itor(header, current)
    local entry = current.next
    if entry ~= header then
        return entry, entry.key, entry.value
    end
end

function hashlist:__pairs()
    return itor, self.header, self.header
end

return EventEngine
